<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue'
import { ElMessage, ElLoading } from 'element-plus'
import { InfoFilled, Search, Refresh } from '@element-plus/icons-vue'
import * as echarts from 'echarts'
import Map from '@arcgis/core/Map'
import MapView from '@arcgis/core/views/MapView'
import FeatureLayer from '@arcgis/core/layers/FeatureLayer'
import Query from '@arcgis/core/rest/support/Query.js'
import gaodeLayer from '@/utils/GaoDeBaseLayer'
import type { Question } from '@/utils/QuestionAnalysisSystem'
import {
  generateHeatmapData,
  calculateQuestionWeight,
  findSimilarQuestions,
  calculateKeywordScore,
  calculateTimeDecayFactor,
  calculateLocationClusterScore,
} from '@/utils/QuestionAnalysisSystem'

// 图表实例引用
const questionHeatmapChartRef = ref<HTMLElement | null>(null)
const keywordAnalysisChartRef = ref<HTMLElement | null>(null)
const timeDecayChartRef = ref<HTMLElement | null>(null)

// 图表实例
let questionHeatmapChart: echarts.ECharts | null = null
let keywordAnalysisChart: echarts.ECharts | null = null
let timeDecayChart: echarts.ECharts | null = null

// 图层引用
let facilityLayer: FeatureLayer | null = null

// 搜索和筛选
const searchKeyword = ref('')
const filterPriority = ref('')
const filterStatus = ref('')

// 统计数据
const analysisData = reactive({
  allQuestions: [] as Question[],
  questionHeatmapData: [] as number[][],
  keywordScores: [] as { keyword: string; score: number }[],
  loading: false,
})

// 筛选后的问题列表
const filteredQuestions = computed(() => {
  return analysisData.allQuestions.filter((question) => {
    const matchesKeyword =
      searchKeyword.value === '' ||
      question.description.toLowerCase().includes(searchKeyword.value.toLowerCase()) ||
      question.type.toLowerCase().includes(searchKeyword.value.toLowerCase()) ||
      question.facilityName.toLowerCase().includes(searchKeyword.value.toLowerCase())

    const matchesPriority =
      filterPriority.value === '' || question.priority === filterPriority.value
    const matchesStatus = filterStatus.value === '' || question.status === filterStatus.value

    return matchesKeyword && matchesPriority && matchesStatus
  })
})

// 选中的问题
const selectedQuestion = ref<Question | null>(null)
const similarQuestions = ref<Question[]>([])

// 初始化
onMounted(() => {
  initCharts()
  loadQuestionData()
})

// 初始化图表
const initCharts = () => {
  // 初始化问题热力图
  if (questionHeatmapChartRef.value) {
    questionHeatmapChart = echarts.init(questionHeatmapChartRef.value)
    const option = {
      title: {
        text: '问题热力图分析',
        left: 'center',
      },
      tooltip: {
        trigger: 'item',
        formatter: function (params: any) {
          return `权重值: ${params.value[2].toFixed(2)}`
        },
      },
      grid: {
        left: '3%',
        right: '4%',
        bottom: '10%',
        containLabel: true
      },
      xAxis: {
        type: 'category',
        data: [],
        name: 'X坐标',
        nameLocation: 'middle',
        nameGap: 30
      },
      yAxis: {
        type: 'category',
        data: [],
        name: 'Y坐标',
        nameLocation: 'middle',
        nameGap: 30
      },
      visualMap: {
        min: 0,
        max: 10,
        calculable: true,
        orient: 'horizontal',
        left: 'center',
        bottom: '5%',
        inRange: {
          color: ['blue', 'green', 'yellow', 'red'],
        },
      },
      series: [
        {
          name: '问题热力图',
          type: 'heatmap',
          data: [],
          pointSize: 8,
          blurSize: 10,
          coordinateSystem: 'cartesian2d'
        },
      ],
    }
    questionHeatmapChart.setOption(option)
  }

  // 初始化关键词分析图表
  if (keywordAnalysisChartRef.value) {
    keywordAnalysisChart = echarts.init(keywordAnalysisChartRef.value)
    const option = {
      title: {
        text: '关键词权重分析',
        left: 'center',
      },
      tooltip: {
        trigger: 'axis',
        axisPointer: {
          type: 'shadow',
        },
      },
      grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true,
      },
      xAxis: {
        type: 'value',
        boundaryGap: [0, 0.01],
      },
      yAxis: {
        type: 'category',
        data: [],
      },
      series: [
        {
          name: '权重分数',
          type: 'bar',
          data: [],
        },
      ],
    }
    keywordAnalysisChart.setOption(option)
  }

  // 初始化时间衰减图表
  if (timeDecayChartRef.value) {
    timeDecayChart = echarts.init(timeDecayChartRef.value)
    const option = {
      title: {
        text: '问题时间衰减分析',
        left: 'center',
      },
      tooltip: {
        trigger: 'axis',
      },
      xAxis: {
        type: 'category',
        data: [],
      },
      yAxis: {
        type: 'value',
        name: '权重系数',
      },
      series: [
        {
          data: [],
          type: 'line',
          smooth: true,
        },
      ],
    }
    timeDecayChart.setOption(option)
  }

  // 初始化地图
  initMap()
}

// 初始化地图
const initMap = () => {
  try {
    // 创建地图实例
    const map = new Map({
      basemap: {
        baseLayers: [gaodeLayer],
      },
    })

    // 创建地图视图
    new MapView({
      container: 'mapDiv',
      map: map,
      center: [116.3, 39.9], // 北京的经纬度
      zoom: 10,
    })

    // 创建学校设施要素图层
    facilityLayer = new FeatureLayer({
      url: 'https://services7.arcgis.com/7XPW9RycLUzz2YAj/arcgis/rest/services/SchoolFacilityManagement/FeatureServer/0',
      outFields: ['*'], // 获取所有字段
    })

    // 添加图层到地图
    map.add(facilityLayer)
  } catch (error) {
    console.error('初始化地图失败:', error)
    ElMessage.error('初始化地图失败')
  }
}

// 加载问题数据
const loadQuestionData = async () => {
  if (!facilityLayer) return

  analysisData.loading = true
  const loadingInstance = ElLoading.service({
    text: '正在加载问题数据...',
    background: 'rgba(0, 0, 0, 0.7)',
  })

  try {
    // 查询所有设施
    const query = new Query({
      where: '1=1', // 查询所有记录
      outFields: ['*'],
      returnGeometry: true,
    })

    const result = await facilityLayer.queryFeatures(query)
    const features = result.features

    // 收集所有问题
    const allQuestions: Question[] = []
    features.forEach((feature) => {
      try {
        const issuesStr = feature.attributes.Issues || '[]'
        const issues = JSON.parse(issuesStr)

        // 收集所有问题并添加位置信息
        if (issues.length > 0) {
          const geometry = feature.geometry as any
          issues.forEach((issue: any) => {
            allQuestions.push({
              ...issue,
              location: {
                x: geometry.x,
                y: geometry.y,
              },
            })
          })
        }
      } catch (e) {
        console.error('解析问题数据失败:', e)
      }
    })

    analysisData.allQuestions = allQuestions

    // 生成问题热力图数据
    if (allQuestions.length > 0) {
      const heatmapData = generateHeatmapData(allQuestions)

      // 处理热力图数据，将坐标转换为离散的类别值
      const xCoords = Array.from(new Set(heatmapData.map(point => Math.round(point.x * 100) / 100)))
        .sort((a, b) => a - b)
      const yCoords = Array.from(new Set(heatmapData.map(point => Math.round(point.y * 100) / 100)))
        .sort((a, b) => a - b)

      // 将连续坐标转换为离散的类别索引
      const heatmapProcessedData = heatmapData.map(point => {
        const xIndex = xCoords.indexOf(Math.round(point.x * 100) / 100)
        const yIndex = yCoords.indexOf(Math.round(point.y * 100) / 100)
        return [xIndex, yIndex, point.value]
      })

      analysisData.questionHeatmapData = heatmapProcessedData

      // 更新热力图的坐标轴数据
      if (questionHeatmapChart) {
        questionHeatmapChart.setOption({
          xAxis: {
            data: xCoords.map(x => x.toString())
          },
          yAxis: {
            data: yCoords.map(y => y.toString())
          }
        })
      }
    }

    // 分析关键词权重
    const keywordWeights = {
      紧急: 0,
      危险: 0,
      安全隐患: 0,
      漏水: 0,
      损坏: 0,
      故障: 0,
      不工作: 0,
      问题: 0,
      建议: 0,
    }

    allQuestions.forEach((question) => {
      const description = question.description.toLowerCase()
      Object.keys(keywordWeights).forEach((keyword) => {
        if (description.includes(keyword.toLowerCase())) {
          keywordWeights[keyword as keyof typeof keywordWeights]++
        }
      })
    })

    analysisData.keywordScores = Object.entries(keywordWeights)
      .filter(([_, count]) => count > 0)
      .map(([keyword, count]) => ({ keyword, score: count }))
      .sort((a, b) => b.score - a.score)

    // 更新图表
    updateCharts()
  } catch (error) {
    console.error('加载问题数据失败:', error)
    ElMessage.error('加载问题数据失败')
  } finally {
    analysisData.loading = false
    loadingInstance.close()
  }
}

// 更新图表
const updateCharts = () => {
  // 更新问题热力图
  if (questionHeatmapChart && analysisData.questionHeatmapData.length > 0) {
    // 计算最大值用于可视化映射
    const maxValue = Math.max(...analysisData.questionHeatmapData.map((item) => item[2]))

    questionHeatmapChart.setOption({
      visualMap: {
        min: 0,
        max: maxValue,
        calculable: true,
      },
      series: [
        {
          data: analysisData.questionHeatmapData,
          coordinateSystem: 'cartesian2d',
          label: {
            show: false
          },
          emphasis: {
            itemStyle: {
              shadowBlur: 10,
              shadowColor: 'rgba(0, 0, 0, 0.5)'
            }
          }
        },
      ],
    })
  }

  // 更新关键词分析图表
  if (keywordAnalysisChart && analysisData.keywordScores.length > 0) {
    keywordAnalysisChart.setOption({
      yAxis: {
        data: analysisData.keywordScores.map((item) => item.keyword),
      },
      series: [
        {
          data: analysisData.keywordScores.map((item) => item.score),
        },
      ],
    })
  }

  // 更新时间衰减图表
  if (timeDecayChart) {
    // 生成过去30天的日期
    const dates = []
    const decayValues = []
    const today = new Date()

    for (let i = 30; i >= 0; i--) {
      const date = new Date(today)
      date.setDate(date.getDate() - i)
      const dateStr = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`
      dates.push(dateStr)
      decayValues.push(calculateTimeDecayFactor(dateStr))
    }

    timeDecayChart.setOption({
      xAxis: {
        data: dates,
      },
      series: [
        {
          data: decayValues,
        },
      ],
    })
  }
}

// 选择问题进行分析
const selectQuestion = (question: Question) => {
  selectedQuestion.value = question

  // 查找相似问题
  if (analysisData.allQuestions.length > 0) {
    similarQuestions.value = findSimilarQuestions(question, analysisData.allQuestions)
  }
}

// 刷新数据
const refreshData = () => {
  loadQuestionData()
}

// 窗口大小变化时重新调整图表大小
window.addEventListener('resize', () => {
  questionHeatmapChart?.resize()
  keywordAnalysisChart?.resize()
  timeDecayChart?.resize()
})
</script>

<template>
  <div class="analysis-container">
    <div class="analysis-header">
      <h2 class="analysis-title">智能问题分析系统</h2>
      <el-button type="primary" @click="refreshData" :loading="analysisData.loading">
        <el-icon><Refresh /></el-icon> 刷新数据
      </el-button>
    </div>

    <div class="analysis-description">
      <el-alert
        title="智能问题分析系统"
        type="info"
        description="基于关键词和多因素的问题优先级评估、时间衰减和位置聚集度分析、问题相似度匹配功能"
        :closable="false"
        show-icon
      />
    </div>

    <div class="analysis-charts">
      <el-row :gutter="20">
        <el-col :span="24">
          <el-card class="chart-card">
            <template #header>
              <div class="card-header">
                <span>问题热力图分析</span>
                <el-tooltip
                  content="基于关键词分析、时间衰减和位置聚集度的智能问题分析系统生成的热力图"
                >
                  <el-icon><info-filled /></el-icon>
                </el-tooltip>
              </div>
            </template>
            <div ref="questionHeatmapChartRef" class="chart-container"></div>
          </el-card>
        </el-col>
      </el-row>

      <el-row :gutter="20" style="margin-top: 20px">
        <el-col :span="12">
          <el-card class="chart-card">
            <template #header>
              <div class="card-header">
                <span>关键词权重分析</span>
                <el-tooltip content="问题描述中包含的关键词出现频率统计">
                  <el-icon><info-filled /></el-icon>
                </el-tooltip>
              </div>
            </template>
            <div ref="keywordAnalysisChartRef" class="chart-container"></div>
          </el-card>
        </el-col>
        <el-col :span="12">
          <el-card class="chart-card">
            <template #header>
              <div class="card-header">
                <span>时间衰减分析</span>
                <el-tooltip content="问题随时间推移的权重衰减曲线">
                  <el-icon><info-filled /></el-icon>
                </el-tooltip>
              </div>
            </template>
            <div ref="timeDecayChartRef" class="chart-container"></div>
          </el-card>
        </el-col>
      </el-row>

      <el-row :gutter="20" style="margin-top: 20px">
        <el-col :span="24">
          <el-card class="question-list-card">
            <template #header>
              <div class="card-header">
                <span>问题列表与相似度分析</span>
                <el-tooltip content="选择问题可查看相似问题匹配结果">
                  <el-icon><info-filled /></el-icon>
                </el-tooltip>
              </div>
            </template>

            <div class="filter-container">
              <el-input
                v-model="searchKeyword"
                placeholder="搜索问题关键词"
                class="filter-item"
                clearable
              >
                <template #prefix>
                  <el-icon><Search /></el-icon>
                </template>
              </el-input>

              <el-select
                v-model="filterPriority"
                placeholder="优先级"
                clearable
                class="filter-item"
              >
                <el-option label="高" value="高" />
                <el-option label="中" value="中" />
                <el-option label="低" value="低" />
              </el-select>

              <el-select v-model="filterStatus" placeholder="状态" clearable class="filter-item">
                <el-option label="待处理" value="待处理" />
                <el-option label="已处理" value="已处理" />
              </el-select>
            </div>

            <div class="questions-container">
              <div class="questions-list">
                <el-table
                  :data="filteredQuestions"
                  style="width: 100%"
                  @row-click="selectQuestion"
                  highlight-current-row
                >
                  <el-table-column prop="facilityName" label="设施名称" min-width="120" />
                  <el-table-column prop="date" label="报告日期" width="100" />
                  <el-table-column prop="type" label="问题类型" width="100" />
                  <el-table-column
                    prop="description"
                    label="问题描述"
                    min-width="200"
                    show-overflow-tooltip
                  />
                  <el-table-column prop="priority" label="优先级" width="80">
                    <template #default="scope">
                      <el-tag
                        :type="
                          scope.row.priority === '高'
                            ? 'danger'
                            : scope.row.priority === '中'
                              ? 'warning'
                              : 'info'
                        "
                      >
                        {{ scope.row.priority }}
                      </el-tag>
                    </template>
                  </el-table-column>
                  <el-table-column prop="status" label="状态" width="100">
                    <template #default="scope">
                      <el-tag :type="scope.row.status === '已处理' ? 'success' : 'warning'">
                        {{ scope.row.status }}
                      </el-tag>
                    </template>
                  </el-table-column>
                </el-table>
              </div>

              <div class="question-analysis" v-if="selectedQuestion">
                <h3>问题分析</h3>
                <el-descriptions :column="1" border>
                  <el-descriptions-item label="问题描述">
                    {{ selectedQuestion.description }}
                  </el-descriptions-item>
                  <el-descriptions-item label="关键词权重">
                    {{ calculateKeywordScore(selectedQuestion).toFixed(2) }}
                  </el-descriptions-item>
                  <el-descriptions-item label="时间衰减因子">
                    {{ calculateTimeDecayFactor(selectedQuestion.date).toFixed(2) }}
                  </el-descriptions-item>
                  <el-descriptions-item label="位置聚集度">
                    {{ calculateLocationClusterScore(analysisData.allQuestions, selectedQuestion) }}
                  </el-descriptions-item>
                  <el-descriptions-item label="综合权重">
                    {{
                      calculateQuestionWeight(selectedQuestion, analysisData.allQuestions).toFixed(
                        2,
                      )
                    }}
                  </el-descriptions-item>
                </el-descriptions>

                <h3 style="margin-top: 20px">相似问题</h3>
                <div v-if="similarQuestions.length > 0">
                  <el-table :data="similarQuestions" style="width: 100%">
                    <el-table-column prop="facilityName" label="设施名称" width="120" />
                    <el-table-column
                      prop="description"
                      label="问题描述"
                      min-width="200"
                      show-overflow-tooltip
                    />
                    <el-table-column prop="priority" label="优先级" width="80">
                      <template #default="scope">
                        <el-tag
                          :type="
                            scope.row.priority === '高'
                              ? 'danger'
                              : scope.row.priority === '中'
                                ? 'warning'
                                : 'info'
                          "
                        >
                          {{ scope.row.priority }}
                        </el-tag>
                      </template>
                    </el-table-column>
                  </el-table>
                </div>
                <el-empty v-else description="未找到相似问题" />
              </div>

              <el-empty v-else description="请选择一个问题进行分析" />
            </div>
          </el-card>
        </el-col>
      </el-row>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.card-header {
  display: flex;
  align-items: center;
  gap: 8px;
}

.analysis-container {
  padding: 20px;
  height: 100%;
  overflow-y: auto;
}

.analysis-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.analysis-title {
  margin: 0;
  color: #1976d2;
  font-size: 24px;
}

.analysis-description {
  margin-bottom: 20px;
}

.chart-card {
  margin-bottom: 20px;
  height: 350px;
}

.question-list-card {
  margin-bottom: 20px;
}

.chart-container {
  height: 300px;
  width: 100%;
}

.filter-container {
  display: flex;
  gap: 10px;
  margin-bottom: 15px;
}

.filter-item {
  width: 200px;
}

.questions-container {
  display: flex;
  gap: 20px;
}

.questions-list {
  flex: 1;
  max-width: 60%;
}

.question-analysis {
  flex: 1;
  max-width: 40%;
}

@media (max-width: 1200px) {
  .questions-container {
    flex-direction: column;
  }

  .questions-list,
  .question-analysis {
    max-width: 100%;
  }
}
</style>
